#region File Description
//-----------------------------------------------------------------------------
// OptionsMenuScreen.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
#endregion

namespace MyXnaGame
{
    /// <summary>
    /// The Select Menu screen is brought up over the top of the main menu
    /// screen, and gives the user a chance to choose levels, etc
    /// </summary>
    class SelectMenuScreen : MenuScreen
    {
        #region Fields
        ContentManager content;

        protected Texture2D menuGraphic;

        const int tileCount = 12;
        List<MenuEntry> menuTiles = new List<MenuEntry>(tileCount);
        MenuEntry back = new MenuEntry("Back");
        static int rowCount = 4;
        static int columnCount = 3;

        #endregion

        #region Initialization

        public override void LoadContent()
        {
            content = ScreenManager.Game.Content;
            this.menuGraphic = content.Load<Texture2D>("MenuGraphics/menubg");

            for (var currentTile = 0; currentTile < tileCount; currentTile++)
            {
                // set graphic for tiles only
                menuTiles[currentTile].MenuGraphic = this.menuGraphic;
            }
        }

        /// <summary>
        /// Constructor.
        /// </summary>
        public SelectMenuScreen()
            : base("Options", columnCount)
        {
            for (var currentTile = 0; currentTile < tileCount; currentTile++)
            {
                // Create our menu entries.
                menuTiles.Add(new MenuEntry(" (" + (currentTile + 1) + ")"));
                // Hook up menu event handlers for tiles
                menuTiles[currentTile].Selected += OptionMenuEntrySelected;
            }

            // hook up menu event for Back
            back.Selected += OnCancel;

            // Add entries to the menu
            for (var currentTile = 0; currentTile < tileCount; currentTile++)
            {
                MenuEntries.Add(menuTiles[currentTile]);
            }


            MenuEntries.Add(back);
        }

        #endregion

        #region Handle Input
        
        /// <summary>
        /// Responds to user input, changing the selected entry and accepting
        /// or cancelling the menu.
        /// </summary>
        public override void HandleInput(InputState input)
        {
            // TODO: no wait, don't override left, right, do up/down instead!
            int farRightColumn = 3;
            var currentRow = menuEntries[selectedEntry].CurrentRow;
            var currentColumn = menuEntries[selectedEntry].CurrentColumn;
            var targetRow = currentRow;
            var targetColumn = currentColumn;
            var prevSelectedEntry = selectedEntry;
            var targetEntry = selectedEntry;


            // Just for grid menu: Move to row above
            if (input.IsMenuUp(ControllingPlayer))
            {
                if (currentRow > 1)
                    selectedEntry -= columnCount;
                
                // correct for Back button below tile grid
                if (currentRow == 0 && currentColumn == 0)
                {
                    // not initialized, set to tile item above back button
                    selectedEntry = menuEntries.Count - 1 - columnCount;
                }

                if (selectedEntry < 0)
                    selectedEntry = menuEntries.Count - 1;
            }

            // Just for grid menu: Move to row below
            if (input.IsMenuDown(ControllingPlayer))
            {
                if (currentRow <= rowCount)
                    selectedEntry += columnCount;

                if (selectedEntry >= menuEntries.Count)
                    selectedEntry = 0;
            }
            // Just like normal menu: Move to the left menu entry (or previous)
            if (input.IsMenuLeft(ControllingPlayer))
            {
                // if (menuTiles[selectedEntry].CurrentColumn == 1)

                selectedEntry--;

                if (selectedEntry < 0)
                    selectedEntry = menuEntries.Count - 1;
            }

            // Just like normal menu: Move to the right menu entry (or next)
            if (input.IsMenuRight(ControllingPlayer))
            {
                selectedEntry++;

                if (selectedEntry >= menuEntries.Count)
                    selectedEntry = 0;
            }


            // Accept or cancel the menu? We pass in our ControllingPlayer, which may
            // either be null (to accept input from any player) or a specific index.
            // If we pass a null controlling player, the InputState helper returns to
            // us which player actually provided the input. We pass that through to
            // OnSelectEntry and OnCancel, so they can tell which player triggered them.
            PlayerIndex playerIndex;

            if (input.IsMenuSelect(ControllingPlayer, out playerIndex))
            {
                OnSelectEntry(selectedEntry, playerIndex);
            }
            else if (input.IsMenuCancel(ControllingPlayer, out playerIndex))
            {
                OnCancel(playerIndex);
            }
        }

        /// <summary>
        /// Event handler for when any Option menu entry is selected.
        /// </summary>
        void OptionMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            string message = "You selected Level " + ((MenuEntry)sender).Text;
            MessageBoxScreen levelMessageBox = new MessageBoxScreen(message, false);
            ScreenManager.AddScreen(levelMessageBox, e.PlayerIndex);
        }
        
        #endregion

        protected override void OnCancel(PlayerIndex playerIndex)
        {
            base.OnCancel(playerIndex);
        }
    }
}
